/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package service;

import entities.Note;
import java.util.Collection;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.Consumes;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.persistence.EntityManager;
import converter.NotesConverter;
import converter.NoteConverter;
import javax.persistence.PersistenceContext;
import javax.ejb.Stateless;
import javax.persistence.Query;

/**
 *
 * @author Alex
 */

@Path("/notes/")
@Stateless
public class NotesResource {
    
    @javax.ejb.EJB
    private NoteResource noteResource;

    @Context
    protected UriInfo uriInfo;

    @PersistenceContext(unitName = "uTaskPU")
    protected EntityManager em;
  
    /** Creates a new instance of NotesResource */
    public NotesResource() {
    }

    /**
     * Get method for retrieving a collection of Note instance in XML format.
     *
     * @return an instance of NotesConverter
     */
    @GET
    @Produces({"application/xml", "application/json"})
    public NotesConverter get(@QueryParam("start")
            @DefaultValue("0") int start, @QueryParam("max")
            @DefaultValue("10") int max, @QueryParam("expandLevel")
            @DefaultValue("1") int expandLevel, @QueryParam("query")
            @DefaultValue("SELECT e FROM Note e WHERE e.endDate IS NULL") String query) {
        return new NotesConverter(getEntities(start, max, query), uriInfo.getAbsolutePath(), expandLevel);
    }

    /**
     * Post method for creating an instance of Note using XML as the input format.
     *
     * @param data an NoteConverter entity that is deserialized from an XML stream
     * @return an instance of NoteConverter
     */
    @POST
    @Consumes({"application/xml", "application/json"})
    public Response post(NoteConverter data) {
        Note entity = data.resolveEntity(em);

        long maxId = 0;
        try {
            maxId = (Long)em.createQuery("SELECT MAX(n.id) FROM Note n").getSingleResult();
        } catch (Exception ex) {
            //no records in db, defaulted to 0
        }
        entity.setId(maxId+1);
        entity.setEndDate(null);
        entity.setNoteId(entity.getId());

        createEntity(entity);
        return Response.created(uriInfo.getAbsolutePath().resolve(entity.getId() + "/")).build();
    }

    /**
     * Returns a dynamic instance of NoteResource used for entity navigation.
     *
     * @return an instance of NoteResource
     */
    @Path("{id}/")
    public NoteResource getNoteResource(@PathParam("id") Long id) {
        noteResource.setId(id);
        noteResource.setEm(em);
        return noteResource;
    }

    @GET
    @Produces({"application/xml", "application/json"})
    @Path("projId={projId}/")
    public NotesConverter getNotesByProject(@PathParam("projId") Long id, 
                                            @QueryParam("history") @DefaultValue("false") boolean history) {
        Query q = null;
        if (history)
            q =  em.createNamedQuery("Note.findByProjectWithHistory").setParameter("projId", id);
        else
            q =  em.createNamedQuery("Note.findByProject").setParameter("projId", id);
        
        NotesConverter converter = new NotesConverter(q.getResultList(), uriInfo.getAbsolutePath(), 1);
        return converter;
    }
    /**
     * Returns all the entities associated with this resource.
     *
     * @return a collection of Note instances
     */
    protected Collection<Note> getEntities(int start, int max, String query) {
        return em.createQuery(query).setFirstResult(start).setMaxResults(max).getResultList();
    }

    /**
     * Persist the given entity.
     *
     * @param entity the entity to persist
     */
    protected void createEntity(Note entity) {
        em.persist(entity);
    }
}
